VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
  Persistable = 0  'NotPersistable
  DataBindingBehavior = 0  'vbNone
  DataSourceBehavior  = 0  'vbNone
  MTSTransactionMode  = 0  'NotAnMTSObject
END
Attribute VB_Name = "LLIterator"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = True
Option Explicit
Private Const CM_ERROR_INVALIDPROCCALL As Integer = 5

Private vm_CurrentItem As LLNode
Private vm_PreviousItem As LLNode

Public Sub init(ByVal headItem As LLNode)
Set vm_CurrentItem = headItem
End Sub

Public Function hasPrevious() As Boolean
If vm_CurrentItem Is Nothing Then
    hasPrevious = False
Else
    hasPrevious = Not (vm_PreviousItem Is Nothing)
End If
End Function

Public Function hasNext() As Boolean
If vm_CurrentItem Is Nothing Then
    hasNext = False
Else
    hasNext = Not (vm_CurrentItem.nextItem Is Nothing)
End If
End Function

Public Function hasCurrent() As Boolean
hasCurrent = Not (vm_CurrentItem Is Nothing)
End Function

Public Sub moveNext()
If vm_CurrentItem Is Nothing Then Err.Raise CM_ERROR_INVALIDPROCCALL

Dim vl_NewItem As LLNode
Set vl_NewItem = vm_CurrentItem

Set vm_CurrentItem = vm_CurrentItem.nextItem

Set vl_NewItem.nextItem = vm_PreviousItem
Set vm_PreviousItem = vl_NewItem
End Sub

Public Sub movePrevious()
If vm_PreviousItem Is Nothing Then Err.Raise CM_ERROR_INVALIDPROCCALL

Dim vl_PrevItem As LLNode
Set vl_PrevItem = vm_PreviousItem

Set vm_PreviousItem = vm_PreviousItem.nextItem

Set vl_PrevItem.nextItem = vm_CurrentItem
Set vm_CurrentItem = vl_PrevItem
End Sub

Public Property Get currentItem() As Variant
If Not vm_CurrentItem Is Nothing Then
    assignVariantVariable currentItem, vm_CurrentItem.data
Else
    currentItem = Empty
End If
End Property

Friend Property Get currentNode() As LLNode
Set currentNode = vm_CurrentItem
End Property

Friend Property Set currentNode(ByVal pr_NewNode As LLNode)
Set vm_CurrentItem = pr_NewNode
End Property

Public Sub moveFirst()
Do While Me.hasPrevious
    movePrevious
Loop
End Sub

Public Sub moveLast()
Do While Me.hasNext
    moveNext
Loop
End Sub

Public Sub linkEndWithIterator(ByVal pr_IteratorToAttach As LLIterator)
Me.moveLast
pr_IteratorToAttach.moveFirst

If currentNode Is Nothing Then
    Set currentNode = pr_IteratorToAttach.currentNode
Else
    Set currentNode.nextItem = pr_IteratorToAttach.currentNode
End If
End Sub

Public Sub linkIteratorWithStart(ByVal pr_IteratorToAttach As LLIterator)
Me.moveFirst
pr_IteratorToAttach.moveLast

If pr_IteratorToAttach.currentNode Is Nothing Then
    Set pr_IteratorToAttach.currentNode = Me.currentNode
Else
    Set pr_IteratorToAttach.currentNode.nextItem = Me.currentNode
End If

pr_IteratorToAttach.moveFirst
Me.init pr_IteratorToAttach.currentNode
End Sub

Private Sub Class_Terminate()
Set vm_CurrentItem = Nothing
Set vm_PreviousItem = Nothing
End Sub
